package com.yixun.qfbao.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.yixun.qfbao.api.service.EstateAdviserService;
import com.yixun.qfbao.api.service.V10BindService;
import com.yixun.qfbao.apidto.*;
import com.yixun.qfbao.apidto.v10dto.SyncChannelIntentionStatusDTO;
import com.yixun.qfbao.dao.AdviserChangeDao;
import com.yixun.qfbao.mapper.EstateAdviserMapper;
import com.yixun.qfbao.model.EstateAdviser;
import com.yixun.qfbao.model.ReportExternal;
import com.yixun.qfbao.model.dto.EstateAdviserDTO;
import com.yixun.qfbao.model.dto.ReportExternalDto;
import com.yixun.qfbao.model.enums.DelFlagEnum;
import com.yixun.qfbao.model.enums.SystemIdEnum;
import com.yixun.qfbao.service.ReportExternalService;
import com.yixun.qfbao.xf.model.CustomerPremises;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.model.enums.ResultEnum;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class EstateAdviserServiceImpl implements EstateAdviserService{
	
	private final static Logger logger=LoggerFactory.getLogger(EstateAdviserServiceImpl.class);
	
	@Autowired
	private EstateAdviserMapper estateAdviserMapper;
	@Autowired
	private CustomerPremisesService customerPremisesService;
	@Autowired
	private AdviserChangeDao adviserChangeDao;
	@Autowired
	private V10BindService v10BindService;
	@Autowired
	private EstateAdviserService estateAdviserService;
	@Autowired
	ReportExternalService reportExternalService;
	
	/**
	 * 批量插入置业顾问，在插入前将已有的楼盘下的所有顾问删除。
	 */
	@Override
	public BatchAddEstateAdviserResDto batchAddEstateAdviser(BatchAddEstateAdviserReqDto batchAddEstateAdviserReqDto) {

		BatchAddEstateAdviserResDto resDto=new BatchAddEstateAdviserResDto();
		/*
		 * 仅巧渠道登录能执行此方法
		 */
		if(!SystemIdEnum.DEVELOPERS.getCode().equals(batchAddEstateAdviserReqDto.getLoginType())) {
			logger.info("Access denied!");
			resDto.setResult(ResultEnum.FAIL.getNo());
			resDto.setResultMsg("Access denied!");
			return resDto;
		}
		Long createdUserId = batchAddEstateAdviserReqDto.getCreateUserId();
		Long premisesId = batchAddEstateAdviserReqDto.getPremisesId();
//		int deleteByPremisesId = estateAdviserMapper.deleteAdvisersByPremisesId(premisesId);
//		logger.debug("deleteByPremisesId {} execute result {}",premisesId,deleteByPremisesId);
		List<EstateAdviser> collect = batchAddEstateAdviserReqDto.getList().stream().map(reqDto->{
			EstateAdviserDTO estateAdviser= new EstateAdviserDTO();
			estateAdviser.setName(reqDto.getName());
			estateAdviser.setPhone(reqDto.getPhone());
			estateAdviser.setCreateUserId(createdUserId);
			estateAdviser.setPremisesId(premisesId);
			estateAdviser.setPartnerId(reqDto.getPartnerId());
			return estateAdviser;
		}).collect(Collectors.toList());
		logger.debug("parameters:{}",JSON.toJSONString(collect));
		int batchInsert = 0;
		if(!CollectionUtils.isEmpty(collect)){
			batchInsert = changeAdviser(premisesId,collect);
//			batchInsert = estateAdviserMapper.batchInsert(collect);
		}else {
			// 若没有传入 置业顾问 则将原有的置业顾问全部删除
			int deleteByPremisesId = estateAdviserMapper.deleteAdvisersByPremisesId(premisesId);
		    logger.debug("deleteByPremisesId {} execute result {}",premisesId,deleteByPremisesId);
		}
		logger.debug("batchInsert execute result {}",batchInsert);
		resDto.setResult(ResultEnum.SUCCESS.getNo());
		return resDto;
		
	}

	/**
	 * 楼盘置业顾问变动
	 * @param premisesId
	 * @param list
	 * @return
	 */
	int changeAdviser(Long premisesId ,List<EstateAdviser> list){
		//查询原有的置业顾问
		List<EstateAdviser> oldList = estateAdviserMapper.listByPremisesId(premisesId);
		/**
		 * 判断原来是否有绑定置业顾问
		 */
		if (CollectionUtils.isEmpty(oldList)) {
			logger.info("楼盘：{},原有的置业顾问:{}",premisesId,oldList);
			//原来无绑定置业顾问 新增的置业顾问全部绑定
			return estateAdviserMapper.batchInsert(list);
		}

		/**
		 * 得到原来绑定 现在取消了的 置业顾问
		 */
		boolean flag;
		List<Long> downList = new ArrayList<>();
		for (EstateAdviser oldAdviser : oldList){
			flag = true;
			for (EstateAdviser newAdviser : list){
				if (null != oldAdviser.getPartnerId() && null != newAdviser.getPartnerId()){
					if ((oldAdviser.getPartnerId()).equals(newAdviser.getPartnerId())){
						flag = false;
						break;
					}
				}
			}
			if (flag){
				downList.add(oldAdviser.getId());
			}
		}
		logger.info("需要删除的置业顾问 adviserIds:{}",downList);
		/**
		 * 得到原来没有绑定 现在新增的绑定的  置业顾问
		 */
		List<EstateAdviser> upList = new ArrayList<>();
		for (EstateAdviser newAdviser : list){
			flag = true;
			for (EstateAdviser oldAdviser : oldList){
				if (null != newAdviser.getPartnerId() && null != oldAdviser.getPartnerId()){
					if ((newAdviser.getPartnerId()).equals(oldAdviser.getPartnerId())){
						flag = false;
						break;
					}
				}
			}
			if (flag){
				upList.add(newAdviser);
			}
		}
		logger.info("需要添加的置业顾问:{}",upList);
		/**
		 * 删除 需要删除的置业顾问
		 */
		if (!CollectionUtils.isEmpty(downList)){
			for (Long adviserId : downList) {
				deleteEstateAdviserById(adviserId);
			}
		}

		//返回新绑定的 置业顾问数量
		if (!CollectionUtils.isEmpty(upList)){
			return estateAdviserMapper.batchInsert(upList);
		}
		return 0;
	}


	@Override
	public ListEstateAdviserByPremisesIdResDto listEstateAdviserByPremisesId(
			ListEstateAdviserByPremisesIdReqDto params) {
			return listAdviserByPremisesId(params.getPremisesId());
	}


	@Override
	public ListEstateAdviserByPremisesIdResDto listEstateAdviserByPremisesId(
			com.yixun.qfbao.apidto.v10dto.Listv10EstateAdviserByPremisesIdReqDto params) {
		return listAdviserByPremisesId(params.getPremisesId());
	}


	private ListEstateAdviserByPremisesIdResDto listAdviserByPremisesId(Long premisesId) {
		ListEstateAdviserByPremisesIdResDto resDto=new ListEstateAdviserByPremisesIdResDto();
		List<EstateAdviser> list=estateAdviserMapper.listByPremisesId(premisesId);
		if(CollectionUtils.isEmpty(list)) {
			resDto.setList(new ArrayList<>());
		}else {
			List<EstateAdviserDto> collect = list.stream().map(estateAdviser->{
				EstateAdviserDto dto=new EstateAdviserDto();
				dto.setId(estateAdviser.getId());
				dto.setAdviserUuid(estateAdviser.getAdviserUuid());
				dto.setPremisesId(estateAdviser.getPremisesId());
				dto.setPartnerId(estateAdviser.getPartnerId());
				dto.setName(estateAdviser.getName());
				dto.setPhone(estateAdviser.getPhone());
				return dto;
			}).collect(Collectors.toList());
			resDto.setList(collect);
		}
		resDto.setResult(ResultEnum.SUCCESS.getNo());
		return resDto;
	}

	@Override
	public int deleteEstateAdviserById(Long adviserId) {
		EstateAdviser estateAdviser = new EstateAdviser();
		estateAdviser.setId(adviserId);
		estateAdviser.setDeleted(DelFlagEnum.DEL.getNo());
		return estateAdviserMapper.edit(estateAdviser);
	}

	@Override
	public int changeCPAdviser(ChangeCPAdviserReqDto reqDto) {
		Long premisesId = reqDto.getPremisesId();
		Long customerPremisesId = reqDto.getCustomerPremisesId();
		String oldAdviser = reqDto.getOldAdviser();
		String newAdviser = reqDto.getNewAdviser();
		List<CustomerPremises> cusPreList = new ArrayList<>();
		if(Objects.nonNull(customerPremisesId)){
			// 指定报备修改置业顾问,不需要原置业顾问字段
			CustomerPremises cusPre = customerPremisesService.selectById(customerPremisesId);
			// 报备记录变更与原值一样,不进行变更操作
			if(newAdviser.equals(cusPre.getAdviserUuid())){
				return 0;
			}
			cusPreList.add(cusPre);
			oldAdviser = null;
		}else {
			CustomerPremisesDto customerPremisesDto = new CustomerPremisesDto();
			customerPremisesDto.setPremisesId(premisesId);
			customerPremisesDto.setAdviserUuid(oldAdviser);
			cusPreList = customerPremisesService.selectListByDto(customerPremisesDto);
		}
		int count = customerPremisesService.changeCPAdviser(premisesId, customerPremisesId,oldAdviser, newAdviser);
		// 添加变更记录
		adviserChangeDao.addAdviserChange(cusPreList, newAdviser, reqDto.getUserId());

		//获取报备绑定关系
		ReportExternalDto reportExternalDto = new ReportExternalDto();
		reportExternalDto.setReportId(cusPreList.get(0).getId());
		reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
		List<ReportExternal> list = reportExternalService.selectListByDto(reportExternalDto);

		/**
		 * 存在绑定关系时，同步至v10
		 */
		if (!CollectionUtils.isEmpty(list)) {
			logger.info("渠道王置业顾问同步至v10 reqDto{}",reqDto);
			SyncChannelIntentionStatusDTO resetSyncDTO = new SyncChannelIntentionStatusDTO();
			resetSyncDTO.setIntentionUuid(list.get(0).getReportUuid());
			resetSyncDTO.setRemark("同步置业顾问");
			resetSyncDTO.setChannelStatusType("2");
			//交易状态保持不变
			resetSyncDTO.setStatus(cusPreList.get(0).getConfirmStatus());
			//查询置业顾问信息
			EstateAdviser adviser = new EstateAdviser();
			adviser.setAdviserUuid(newAdviser);
			EstateAdviser estateAdviser = estateAdviserService.selectOne(adviser);
			resetSyncDTO.setAdviserName(estateAdviser.getName());
			resetSyncDTO.setAdviserPhone(estateAdviser.getPhone());
			//调用同步v10的接口
			v10BindService.syncChannelIntentionStatus(resetSyncDTO);
		}
		return count;
	}

	@Override
	public int getCPCountByAdviser(GetCPCountByAdviserReqDto reqDto) {
		CustomerPremisesDto customerPremisesDto = new CustomerPremisesDto();
		customerPremisesDto.setAdviserUuid(reqDto.getAdviserUuid());
		return customerPremisesService.count(customerPremisesDto);
	}

    @Override
    public EstateAdviser getAdviserByUuid(String uuid) {
        return estateAdviserMapper.getAdviserByUuid(uuid);
    }

	@Override
	public List<EstateAdviser> selectListByPartner(Long partnerId) {
		return estateAdviserMapper.selectListByPartner(partnerId);
	}
	
	@Override
	public List<EstateAdviser> selectListByPartnerAndPremises(Long partnerId, List<Long> premisesIds) {
		return estateAdviserMapper.selectListByPartnerAndPremises(partnerId, premisesIds);
	}

	@Override
	public EstateAdviser add(EstateAdviser record) {
		record.setCreateTime(Calendar.getInstance().getTime());
		estateAdviserMapper.insertSelective(record);
		return record;
	}

	@Override
	public EstateAdviser selectOne(EstateAdviser record) {
		return estateAdviserMapper.selectOne(record);
	}
}
